<template>

  <div class="container">
    <div id="cesiumContainer"></div>
    <div id="mask"></div>
    <div id="threeContainer" ref="threeElRef"></div>
    <div class="move-box">
      <div class="move-item" @click="moveAction('up')">上</div>
      <div class="move-item" @click="moveAction('down')">下</div>
      <div class="move-item" @click="moveAction('left')">左</div>
      <div class="move-item" @click="moveAction('right')">右</div>
    </div>
    <div class="scale-box scale-x-box">
      <div class="scale-item" @click="scaleXAction('in')">X缩小</div>
      <div class="scale-item" @click="scaleXAction('out')">X放大</div>
    </div>
    <div class="scale-box scale-y-box">
      <div class="scale-item" @click="scaleYAction('in')">Y缩小</div>
      <div class="scale-item" @click="scaleYAction('out')">Y放大</div>
    </div>
    <div class="scale-box scale-z-box">
      <div class="scale-item" @click="scaleZAction('in')">Z缩小</div>
      <div class="scale-item" @click="scaleZAction('out')">Z放大</div>
    </div>
    <div class="scale-box change-box">
      <div class="scale-item" @click="onChangeModel(1)">管道</div>
      <div class="scale-item" @click="onChangeModel(2)">切面</div>
    </div>
  </div>
</template>

<script setup>
import * as Cesium from 'cesium';
import * as THREE from 'three';
import {Vector2,Raycaster} from 'three'
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { initCesium } from 'cesium_dev_kit'
const threeElRef = ref()
let dirLight;
let center = [77.25416,38.41029];
let coords = [...center, 200];
let hpr = {
  heading: 0,
  pitch:-45,
  roll: 0
}
const tianKey = 'd786b5f312e2a5dee39b667a5805263c'
let model
let app
let threeObj = {
  scene: null,
  camera: null,
  renderer: null,
}
onMounted(() => {
  initMap()
  addTdtLayer({
    type: 'img_w'
  })
  addTdtLayer({
    type: 'cia_w'
  })
  document.addEventListener('click',clickEvent, false )
})
const initMap = () => {
  app = new initCesium({
    cesiumGlobal: Cesium,
    threeGlobal: THREE,
    containerId: 'cesiumContainer',
    threeContainerId: 'threeContainer',
    viewerConfig: {
      useDefaultRenderLoop: false,
      selectionIndicator: false,
      sceneModePicker: false
    },
    extreaConfig: {
      depthTest: true
    },
  })
  initThree(app.threeJs);
}
const onChangeModel = (type) => {
  threeObj.scene.clear()
  initLight(type)
  const loader = new GLTFLoader();
  switch(type) {
    case 1:
      loader.load("/gds.glb", function (gltf) {
        model = gltf.scene;
        model.scale.set(0.9999,0.5,0.5);
        model.position.set(-730,20,82);
        threeObj.scene.add(model);
        model.traverse(function (object) {
          if (object.isMesh) {
            object.castShadow = true;
          }
        });
        app.threeJs.loop(function () {
          threeObj.scene.update();
        })
      })
      break;
    case 2:
      loader.load("/shebei.glb", function (gltf) {
        model = gltf.scene;
        model.scale.set(0.9999,0.5,0.5);
        model.position.set(-730,100,82);
        threeObj.scene.add(model);
        model.traverse(function (object) {
          if (object.isMesh) {
            object.castShadow = true;
          }
        });
        app.threeJs.loop(function () {
          threeObj.scene.update();
        })
      })
      break;
  }
}

const initThree =  (ThreeJs) => {
  threeObj = ThreeJs.initThree({ center, threeHabit: false, });
  onChangeModel(1)
  enableShadow(threeObj.renderer)
  flyto(coords, hpr);
}
const initLight = (type) => {
  let hemiLight
  switch(type) {
    case 1:
      hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444)
      threeObj.scene.add(hemiLight);
      dirLight = new THREE.DirectionalLight(0xffffff)
      dirLight.position.set(0, 0, 0)
      threeObj.scene.add(dirLight);
      break;
    case 2:
      hemiLight = new THREE.HemisphereLight(0x444444, 0x999999)
      threeObj.scene.add(hemiLight);
      dirLight = new THREE.DirectionalLight(0x888888)
      dirLight.position.set(0, 0, 0)
      threeObj.scene.add(dirLight);
      break;
  }

}
const addTdtLayer = (options) => {
  let url = `https://t{s}.tianditu.gov.cn/DataServer?T=${options.type}&x={x}&y={y}&l={z}&tk=${tianKey}`
  const layerProvider = new Cesium.UrlTemplateImageryProvider({
    url: url,
    subdomains: ['0','1','2','3','4','5','6','7'],
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    maximumLevel: 18
  });
  app.viewer.imageryLayers.addImageryProvider(layerProvider);
}
const enableShadow = (renderer) => {
  renderer.shadowMap.enabled = true;
  dirLight.castShadow = true;
}
const flyto = (coords, hpr) => {
  app.passEffect.flyTo({
    position: Cesium.Cartesian3.fromDegrees(coords[0], coords[1], coords[2]),
    orientation: {
      heading: Cesium.Math.toRadians(hpr.heading),
      pitch: Cesium.Math.toRadians(hpr.pitch),
      roll: Cesium.Math.toRadians(hpr.roll),
    },
    duration: 1.5
  })
}
const mouse = new Vector2()
const rayCaster = new Raycaster()
const clickEvent = (event) => {
  if (!threeElRef.value) {
    return
  }
  // 得到鼠标相对于容器的坐标, 如果是div容器，需要改成div的宽高以及用event.layerX layerY
  // mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  // mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
  mouse.x = ( event.layerX / threeElRef.value.offsetWidth ) * 2 - 1;
  mouse.y = - ( event.layerY / threeElRef.value.offsetHeight ) * 2 + 1;

  // 执行射线检测
  rayCaster.setFromCamera(mouse, threeObj.camera);
  // 射线涉及到的物体集合
  const intersects = rayCaster.intersectObjects(threeObj.scene.children, true)
  intersects.forEach((item) => {
    const mesh = item.object
    console.log('mesh', mesh)

  })
}

let pos
let scale
const moveAction = (dir) => {
  pos = model.position
  switch(dir) {
    case 'up':
      pos.z+=1
      break;
    case 'down':
      pos.z-=1
      break;
    case 'left':
      pos.x-=10
      break;
    case 'right':
      pos.x+=10
      break;
  }
  console.log('position', pos)
  model.position.set(pos.x, pos.y,pos.z)
}
const scaleXAction = (dir) => {
  scale = model.scale
  switch(dir) {
    case 'in':
      scale.x-=0.1
      break;
    case 'out':
      scale.x+=0.1
      break;
  }
  console.log('scale', scale)
  model.scale.set(scale.x, scale.y,scale.z)
}
const scaleYAction = (dir) => {
  scale = model.scale
  switch(dir) {
    case 'in':
      scale.y-=0.1
      break;
    case 'out':
      scale.y+=0.1
      break;
  }
  console.log('scale', scale)
  model.scale.set(scale.x, scale.y,scale.z)
}
const scaleZAction = (dir) => {
  scale = model.scale
  switch(dir) {
    case 'in':
      scale.z-=0.1
      break;
    case 'out':
      scale.z+=0.1
      break;
  }
  console.log('scale', scale)
  model.scale.set(scale.x, scale.y,scale.z)
}
</script>

<style scoped>
.container{
  /*position: relative;*/
  width: 100%;
  height: 100%;
}
#cesiumContainer{
  position: absolute;
  width: 100%;
  height: 100%;
  top:0;
  left:0;
  overflow: hidden;
}
#mask{
  position: absolute;
  width: 100%;
  height: 100%;
  top:0;
  left:0;
  background: rgba(0,0,0,0.5);
  overflow: hidden;
  pointer-events: none;
}
#threeContainer{
  position: absolute;
  width: 100%;
  height: 100%;
  top:0;
  left:0;
  overflow: hidden;
  pointer-events: none;
}
.move-box{
  position: absolute;
  background: rgba(0,0,0,0.7);
  right:20px;
  top:20px;
  padding: 10px;
  border-radius: 5px;
  display: flex;
}
.move-item{
  margin-right: 10px;
  padding: 1px 10px;
  border-radius: 3px;
  background: #f2f2f2;
  cursor: pointer;
}
.scale-box{
  position: absolute;
  background: rgba(0,0,0,0.7);
  right:20px;
  top:100px;
  padding: 10px;
  border-radius: 5px;
  display: flex;
}
.scale-x-box{
  top:100px;
}
.scale-y-box{
  top:180px;
}
.scale-z-box{
  top:260px;
}
.change-box{
  top:340px;
}
.scale-item{
  margin-right: 10px;
  padding: 1px 10px;
  border-radius: 3px;
  background: #f2f2f2;
  cursor: pointer;
}
</style>
